package com.yzd.learnjava.generics;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import com.yzd.learnjava.util.Print;
import com.yzd.learnjava.util.SimpleQueue;

public class Apply {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException {
		List<Shape> shapes = new ArrayList<Shape>();
		for(int i = 0 ; i < 10 ; i++) {
			shapes.add(new Shape());
		}
		Apply.apply(shapes, Shape.class.getMethod("rotate"));
		Apply.apply(shapes, Shape.class.getMethod("resize", int.class), 5);
		
		List<Squar> squars = new ArrayList<Squar>();
		for(int i = 0 ; i < 10 ; i++) {
			squars.add(new Squar());
		}
		Apply.apply(squars, Squar.class.getMethod("rotate"));
		Apply.apply(shapes, Squar.class.getMethod("resize", int.class), 5);
		
		Apply.apply(new FilledList<Shape>(Shape.class, 10), Shape.class.getMethod("rotate"));
		Apply.apply(new FilledList<Shape>(Squar.class, 10), Shape.class.getMethod("rotate"));
		
		SimpleQueue<Shape> shapeQ = new SimpleQueue<Shape>();
		for(int i = 0 ; i < 10; i++) {
			shapeQ.add(new Shape());
			shapeQ.add(new Squar());
		}
		
		Apply.apply(shapeQ, Shape.class.getMethod("rotate"));
	}
	
	public static <T, S extends Iterable<? extends T>> void apply(S seq, Method f , Object ... args) {
		try {
			for(T t : seq) {
				f.invoke(t, args);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

class Shape {
	public void rotate() {
		Print.print(this + " rotate");
	}
	public void resize(int newSize) {
		Print.print(this + " resize " + newSize);
	}
}

class Squar extends Shape{}

class FilledList<T> extends ArrayList<T>{
	public FilledList(Class<? extends T> type, int size) {
		try {
			for(int i = 0 ; i < size ; i++) {
				add(type.newInstance());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}





















